import type { Response } from 'express'
import { Body, Controller, Delete, Get, HttpException, HttpStatus, Param, Post, Query, Req, Res } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'
import { JwtNeed } from '@/common/decorator'
import { PlayerUserService } from '../user/player-user.service'
import { CreateSubscribeDto, FindSubscribeDto, ListPageSubscribeDto, WebCreateSubscribeDto } from './dto/subscribe.dto'
import { SubscribeService } from './subscribe.service'

@ApiTags('后台/二期/预约管理')
@Controller('subscribe')
export class SubscribeController {
  constructor(
    private readonly subscribeService: SubscribeService,
    private readonly playerUserService: PlayerUserService,
  ) {}

  /**
   * 导出预约
   */
  @Get('export')
  async export(@Res() res: Response) {
    const buffer = await this.subscribeService.export()

    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    res.setHeader('Content-Disposition', 'attachment; filename=subscribe.xlsx')
    res.end(buffer)
  }

  /**
   * 预约列表
   */
  @Get()
  page(@Query() query: ListPageSubscribeDto) {
    return this.subscribeService.findPage(query)
  }

  /**
   * 预约详情
   */
  @Get(':subscribeId')
  detail(@Param('subscribeId') subscribeId: number) {
    return this.subscribeService.findOne({ subscribeId })
  }

  /**
   * 添加预约
   */
  @Post()
  async create(@Body() data: CreateSubscribeDto) {
    const player = await this.playerUserService.findOne({ where: { uid: data.userUid } })
    if (!player) {
      throw new HttpException('用户不存在', HttpStatus.UNAUTHORIZED)
    }

    return this.subscribeService.create(data)
  }

  /**
   * 删除预约
   */
  @Delete(':subscribeId')
  async remove(@Param('subscribeId') subscribeId: number) {
    await this.subscribeService.removeAndUpdateUserSubscribe(subscribeId)
  }
}

@ApiTags('官网/二期/预约')
@Controller('web/subscribe')
export class WebSubscribeController {
  constructor(
    private readonly subscribeService: SubscribeService,
    private readonly playerUserService: PlayerUserService,
  ) {}

  /**
   * 立即预约
   */
  @Post()
  @JwtNeed()
  async webCreate(@Req() req: Request, @Body() data: WebCreateSubscribeDto) {
    if (!req.user?.uid) {
      throw new HttpException('请先登录', HttpStatus.UNAUTHORIZED)
    }

    const player = await this.playerUserService.findOne({ where: { uid: req.user.uid } })
    if (player.isReserved) {
      throw new HttpException('用户已预约', HttpStatus.BAD_REQUEST)
    }
    if (req.user.uid === data.inviteUserUid) {
      throw new HttpException('不能邀请自己', HttpStatus.BAD_REQUEST)
    }

    await this.playerUserService.reservation(req.user.uid, data.inviteUserUid)

    if (data.inviteUserUid) {
      const invitePlayer = await this.playerUserService.findOne({ where: { uid: data.inviteUserUid } })
      if (!invitePlayer) {
        throw new HttpException('邀请用户不存在', HttpStatus.BAD_REQUEST)
      }

      // 抽奖次数+1
      this.playerUserService.update({ uid: data.inviteUserUid }, { canDrawCount: player.inviteCount + 1 })
    }
    this.subscribeService.create({
      inviteUserUid: data.inviteUserUid,
      userUid: req.user.uid,
      subscribePhone: req.user.phone,
    })

    // 任务完成次数+1 Todo
  }
}
